﻿using GameControl;
using QxFramework.Core;
using System;
using UnityEngine;
using UnityEngine.VFX;
using System.Collections.Generic;
using DG.Tweening;
///[RequireComponent(typeof(Collider2D))]

public abstract class Item : MonoBehaviour
{
    /// <summary>
    /// 是否有销毁时的特效
    /// </summary>
    [HideInInspector]
    public bool HaveDestoryEffects = true;
    public abstract ItemField ItemFieldSetting { get; set; }
    public string Abstract = "这里是物体介绍";
    /// <summary>
    /// 物体放置到场景中时执行的函数,在OnAwake后执行,从内存池中加载会再次执行此函数
    /// </summary>
    public abstract void OnStart();

    public T GetField<T>()where T:ItemField{
        return ItemFieldSetting as T;
    }
    public virtual float RotationInDegree
    {
        get
        {
            return transform.eulerAngles.z;
        }
        set
        {
            transform.eulerAngles = new Vector3(0, 0, value);
        }
    }

    //  public ItemField itemFieldSetting;
    /// <summary>
    /// 初始化物体的各个参数
    /// </summary>
    /// <param name="args"></param>
    public virtual void DownloadInstanceField(object args)
    {
        ItemFieldSetting = args as ItemField;
        this.transform.localEulerAngles =new Vector3(0,0, (args as ItemField).Rotation);
        this.transform.position = (args as ItemField).Position;
        Vector3 scale = this.transform.localScale;
        if ((args as ItemField).IsFliped)
        {
            scale.x = Mathf.Abs(scale.x) * -1;
        }
        else
        {
            scale.x = Mathf.Abs(scale.x);
        }
        this.transform.localScale = scale;
    }
    public virtual ItemField UploadInstanceField()
    {
        ItemFieldSetting.IsFliped = this.transform.localScale.x < 0 ? true : false;
        ItemFieldSetting.Position = this.transform.position;
        ItemFieldSetting.Rotation = this.transform.localEulerAngles.z;
        return ItemFieldSetting;
    }
    public abstract Sprite Sprite { get; }
    /// <summary>
    /// 初始化物体的各个设置,比如设置好对某个物体的引用.
    /// </summary>
    public virtual void OnAwake()
    {

    }
    public virtual void FixedUpdateInLogic()
    {
        
    }
    public virtual void FixedUpdateInPresentation()
    {

    }
    public virtual void OnPreferenceDestory()
    {

    }
    public void DestoryEffect()
    {
        if (HaveDestoryEffects)
        {
            try
            {

            GameObject obj = new GameObject();
            obj.AddComponent<SpriteRenderer>();
            obj.GetComponent<SpriteRenderer>().sprite = this.Sprite;
            obj.AddComponent<PolygonCollider2D>();
            obj.AddComponent<Explodable>().shatterType = Explodable.ShatterType.Voronoi;

            obj.transform.position = this.transform.position;
            obj.transform.eulerAngles = this.transform.eulerAngles;
            obj.layer = 10;
            obj.AddComponent<ExplosionForce>();
            obj.name = this.name + "_piece";


            Explodable piece = obj.GetComponent<Explodable>();
            float siz = obj.GetComponent<SpriteRenderer>().size.x * obj.GetComponent<SpriteRenderer>().size.y;
            //按图像大小适配分裂碎片个数
            piece.extraPoints = Mathf.RoundToInt(siz * 3);
            piece.GenerateFragments();
            piece.explode();
            foreach (GameObject x in piece.fragments)
            {
                Destroy(x, 3.0f);
                x.GetComponent<Rigidbody2D>().mass = 0.01f;
                x.GetComponent<Rigidbody2D>().AddForce(new Vector2(UnityEngine.Random.Range(0, 3), UnityEngine.Random.Range(0, 3)));
                ///先写死层级为2
                x.GetComponent<MeshRenderer>().sortingOrder = 2;
                x.gameObject.layer = obj.layer;
            }
            }
            catch(Exception e)
            {
                
            }
        }
    }
    public virtual void OnRealDestory()
    {
            DestoryEffect();
    }
    static int[] fx = { 0, -1, 0, 1 };
    static int[] fy = { 1, 0, -1, 0 };
    public static Vector3Int GetMeshPosInWorldDirection(CombinableItemField field,int dir)
    {
        Debug.Assert(field.BelongingType == ItemBelongingType.Bench);
        if (field.MeshTransform.IsFlipedInMesh && ((dir % 2) == 1))
        {
            dir += 2;
        }
        dir += field.MeshTransform.MeshRotate;
        //dir += field.MeshTransform.MeshRotate*(field.IsFliped?-1:1)+4;//Mathf.RoundToInt(field.MeshTransform.MeshRotate);
        dir %= 4;
        int nx = fx[dir], ny = fy[dir];
        Vector3Int ans = field.MeshTransform.BenchMeshPos+new Vector3Int(nx,ny,0);
        return ans;
    }
    public virtual void OnDamage(float damage)
    {
        damage *= -1;
        var sprites = this.transform.GetComponentsInChildren<SpriteRenderer>();
        foreach (var x in sprites)
        {
        //    Color origin = x.color;
            x.color = Color.red;
            //可设置受伤动画时间
            x.DOColor(Color.white, 0.5f);
            GameObject clone = ResourceManager.Instance.Instantiate("Prefabs/Effects/DamageText");
            clone.transform.position = this.transform.position;
            clone.GetComponentInChildren<TextMesh>().text = ((damage < 0) ? "" : "+") + damage.ToString();
        }
        
    }
    public virtual void OnRecover(float recover)
    {

    }
    public virtual void OnCollisionEnter2D(Collision2D collision)
    {
        if(GameManager.Get<IItemHealthManager>().CheckIfCanCollide(collision.otherCollider.GetItemName(),
            collision.collider.GetItemName()))
        GameControl.GameManager.Get<GameControl.IPhysicalDamageManager>().OnCollisionHappen(collision.otherCollider.GetItemName(), 
            collision.collider.GetItemName(), collision.GetImpactForce());
    }

}

//[RequireComponent(typeof(Rigidbody2D))]
public class ItemPhysic : MonoBehaviour
{
    Rigidbody2D _rigid;

    public Rigidbody2D Rigid
    {
        set
        {
            _rigid = value;
        }
        get
        {
            return _rigid;
        }
    }
 //   Transform _trans;
    private void Awake()
    {
       // _rigid = GetComponent<Rigidbody2D>();
   //     _trans = GetComponent<Transform>();
    }

    public void UpdatePhysic(ItemPhysicTransform newTransform)
    {
     //   _rigid = GetComponentInParent<Rigidbody2D>();
        _rigid.velocity = newTransform.Velocity;
        _rigid.angularVelocity = newTransform.AngleVelocity;
        _rigid.transform.rotation = Quaternion.Euler(0, 0, newTransform.Angle);
   //     _trans.position = newTransform.Position;
    }
    public ItemPhysicTransform PhysicTransform
    {
        get
        {

        //    _rigid = GetComponentInParent<Rigidbody2D>();
            if (_rigid == null)
            {
                return new ItemPhysicTransform
                {
                    //           Position = _trans.position,
                    Angle = this.transform.eulerAngles.z,
                    Velocity = Vector3.zero,
                    AngleVelocity = 0
                };
            }
            return new ItemPhysicTransform
            {
       //         Position = _trans.position,
                Angle = _rigid.transform.rotation.eulerAngles.z,
                Velocity = _rigid.velocity,
                AngleVelocity = _rigid.angularVelocity
            };
        }
    }
}
//[AttributeUsage(AttributeTargets.All,Inherited =true)]
[Serializable]
public class ItemField
{
    /// <summary>
    /// ItemTypeName+ItemInstanceID
    /// </summary>
   [HideInInspector]
    public string ItemName;
    [HideInInspector]
    public string User;
    [Header("血量")]
    public float Blood=100;

    [Header("物防")]
    public float Soildity=1000;
    [Header("魔防")]
    public float MagicDefence=100;
    [Header("质量")]
    public float Mass=1;
    [Header("属性")]
    public Element Element;

    /// <summary>
    /// 物体锋利程度 用于对物理碰撞伤害的加成
    /// </summary>
    [Header("锋利度")]
    public float Sharpness = 1;

    [HideInInspector]
    public Vector3 Position;
    [HideInInspector]
    public bool IsFliped;
    [HideInInspector]
    public float Rotation;

    /// <summary>
    /// 此物体是否执行Item组件上的FixedUpdateInLogic/FixedUpdateInPreference
    /// </summary>
    [HideInInspector]
    public bool IsUpdate = true;

 //   public ItemPhysicTransform PhysicTransform;
  //  public ItemMeshTransform MeshTransform;
}
[Serializable]
public class ItemPhysicTransform
{
 //   public Vector3 Position;
    public float Angle;
    public Vector3 Velocity;
    public float AngleVelocity;
}
/// <summary>
/// 可拼装物体的网格信息
/// </summary>
[Serializable]
public class ItemMeshTransform
{
    public Vector3Int BenchMeshPos;
    /*/// <summary>
    /// 此物体左下角网格在世界中的坐标
    /// </summary>
    public Vector3Int WorldMeshPos;*/
    //0,1,2,3分别代表上左下右
    public int MeshRotate;

    public bool IsFlipedInMesh;
    /// <summary>
    /// 相对组合体的本地旋转
    /// </summary>
   // public float LocalRotate;
  //  public bool IsFliped;
}
[Serializable]
public enum ItemBelongingType
{
    Map, Bag, Bench
}
[Serializable]
public enum Element
{
    Default,
    Wood,
    Stone,
    Iron,
    Fire,
    Ice,
    Water,
    Mud,
    Lava,
}